"""
Pytest配置文件
"""
import pytest
import sys
import os
from pathlib import Path

# 添加项目根目录到Python路径
project_root = Path(__file__).parent.parent
sys.path.insert(0, str(project_root))

# 测试配置
pytest_plugins = []


@pytest.fixture(scope="session")
def app():
    """创建FastAPI应用实例"""
    from main import app
    return app


@pytest.fixture(scope="session")
def client(app):
    """创建测试客户端"""
    from fastapi.testclient import TestClient
    with TestClient(app) as client:
        yield client


@pytest.fixture(scope="function")
def db_session():
    """创建测试数据库会话"""
    from core.database import SessionLocal, create_tables
    from sqlalchemy.orm import sessionmaker
    from sqlalchemy import create_engine
    import tempfile
    import os
    
    # 创建临时数据库
    temp_db = tempfile.NamedTemporaryFile(suffix='.db', delete=False)
    temp_db.close()
    
    # 更新数据库URL
    original_db_url = os.environ.get('DATABASE_URL')
    os.environ['DATABASE_URL'] = f'sqlite:///{temp_db.name}'
    
    # 创建数据库引擎
    engine = create_engine(os.environ['DATABASE_URL'], connect_args={"check_same_thread": False})
    TestingSessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
    
    # 创建表
    create_tables()
    
    # 创建会话
    db = TestingSessionLocal()
    try:
        yield db
    finally:
        db.close()
        # 恢复原始数据库URL
        if original_db_url:
            os.environ['DATABASE_URL'] = original_db_url
        else:
            os.environ.pop('DATABASE_URL', None)
        # 删除临时数据库
        os.unlink(temp_db.name)


@pytest.fixture(scope="function")
def test_user(db_session):
    """创建测试用户"""
    from models.user import User
    from core.auth import init_auth_data
    
    # 初始化认证数据
    init_auth_data(db_session)
    
    # 创建测试用户
    user = User(
        username="testuser",
        email="test@example.com",
        password="testpass123",
        full_name="测试用户",
        is_active=True
    )
    db_session.add(user)
    db_session.commit()
    db_session.refresh(user)
    
    return user


@pytest.fixture(scope="function")
def auth_headers(client, test_user):
    """获取认证头"""
    # 登录获取token
    response = client.post("/api/auth/login", json={
        "username": "testuser",
        "password": "testpass123"
    })
    
    assert response.status_code == 200
    data = response.json()
    token = data["access_token"]
    
    return {"Authorization": f"Bearer {token}"}


@pytest.fixture(scope="function")
def admin_headers(client):
    """获取管理员认证头"""
    # 登录获取token
    response = client.post("/api/auth/login", json={
        "username": "admin",
        "password": "admin"
    })
    
    assert response.status_code == 200
    data = response.json()
    token = data["access_token"]
    
    return {"Authorization": f"Bearer {token}"}


# 测试配置
def pytest_configure(config):
    """pytest配置"""
    config.addinivalue_line(
        "markers", "slow: marks tests as slow (deselect with '-m \"not slow\"')"
    )
    config.addinivalue_line(
        "markers", "integration: marks tests as integration tests"
    )
    config.addinivalue_line(
        "markers", "unit: marks tests as unit tests"
    )


def pytest_collection_modifyitems(config, items):
    """修改测试收集"""
    for item in items:
        # 根据文件路径添加标记
        if "integration" in str(item.fspath):
            item.add_marker(pytest.mark.integration)
        elif "unit" in str(item.fspath):
            item.add_marker(pytest.mark.unit)
        else:
            item.add_marker(pytest.mark.unit)